package com.shadowtorcher.TableRolePlayingSystem.DataStructure;

import java.util.ArrayList;
import java.util.HashMap;

public class DataProcessor {
    public static String buildString(DataSegment dataSegment) {
        StringBuilder mainStringBuilder = new StringBuilder();
        for (HashMap.Entry<String, SegmentItem> entry : dataSegment.map.entrySet()) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(entry.getKey());
            stringBuilder.append("=");
            if (entry.getValue().isString()) {
                // for String
                stringBuilder.append(escape(entry.getValue().toString()));
            } else if (entry.getValue().isSegment()) {
                // for DataSegment
                stringBuilder.append(DataProcessor.buildString(entry.getValue().getDataSegment()));
            } else if (entry.getValue().isArray()) {
                // for Array
                stringBuilder.append("[");
                for (String i : entry.getValue().getArray()) {
                    stringBuilder.append(escape(i)).append(",");
                }
                stringBuilder.append("]");
            } else {
                throw new RuntimeException("未知错误");
            }
            mainStringBuilder.append(stringBuilder.toString()).append("&");
        }
        return "{" + mainStringBuilder.toString() + "}";
    }

    public static DataSegment buildSegment(String string) {
        DataSegment dataSegment = new DataSegment();
        ArrayList<String> arrayList = split(string);
        int end = readSegment(arrayList, 0, dataSegment);
        assert end == arrayList.size();
        return dataSegment;
    }

    public static int readSegment(ArrayList<String> strings, int start, DataSegment dataSegment) {
        assert strings.get(start).equals("{"); // Segment 第一个字符一定是 { , 随后是一个字符串
        start += 1;

        while (!strings.get(start).equals("}")) {
            String key = strings.get(start);
            start += 1;

            assert strings.get(start).equals("="); // 字符串一定是 key 随后是等号
            start += 1;

            switch (strings.get(start)) {
                case "{":
                    DataSegment subSegment = new DataSegment();
                    start = readSegment(strings, start, subSegment);
                    dataSegment.put(key, subSegment);
                    break;
                case "[":
                    ArrayList<String> arrayList = new ArrayList<>();
                    start = readArray(strings, start, arrayList);
                    dataSegment.put(key, arrayList);
                    break;
                default:
                    dataSegment.put(key, strings.get(start));
                    start += 1;
                    break;
            }
            assert strings.get(start).equals("&");
            start += 1;
        }
        start += 1;
        return start;
    }

    public static int readArray(ArrayList<String> strings, int start, ArrayList<String> arrayList) {
        assert strings.get(start).equals("["); // Array 的第一个字符一定是 [, 随后是字符串 TODO 或 { 支持嵌套
        start += 1;
        while (!strings.get(start).equals("]")) {
            arrayList.add(strings.get(start));
            start += 1;
            assert strings.get(start).equals(",");
            start += 1;
        }
        start += 1;
        return start;
    }

    public static ArrayList<String> split(String str) {
        ArrayList<String> ans = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
        boolean escape = false;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            switch (ch) {
                case '\\':
                    if (escape == true) {
                        stringBuilder.append(ch);
                        escape = false;
                        break;
                    }
                    escape = true;
                    break;
                case '{':
                case '}':
                case ']':
                case '[':
                case '=':
                case '&':
                case ',':
                    if (escape == true) {
                        stringBuilder.append(ch);
                        escape = false;
                    } else {
                        String tmp = stringBuilder.toString();
                        if (!tmp.isEmpty()) {
                            ans.add(stringBuilder.toString());
                            stringBuilder = new StringBuilder();
                        }
                        ans.add(Character.toString(ch));
                    }
                    break;
                default:
                    stringBuilder.append(ch);
                    break;
            }
        }
        return ans;
    }

    private static String escape(String string) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < string.length(); ++i) {
            char ch = string.charAt(i);
            switch (ch) {
                case '{':
                case '}':
                case '[':
                case ']':
                case ',':
                case '\\':
                case '&':
                case '=':
                    stringBuilder.append("\\");
                default:
                    stringBuilder.append(ch);
                    break;
            }
        }
        return stringBuilder.toString();
    }
}
